#ifndef COOLPOOL_SIMULATION_ENTITIES_ENTITY_H_
#define COOLPOOL_SIMULATION_ENTITIES_ENTITY_H_

#include <boost/thread.hpp>

#include "BoundingCylinder.h"
#include "IRenderable.h"

namespace coolpool
{
	// The base of all the objects of the simulation, it contains all the methods
	// which are needed by the renderer and the simulation itself.
	class Entity
	{
	public:
		virtual ~Entity();

		// Bounding sphere of the object, needed only for optimalization purposes.
		virtual const BoundingCylinder & getBoundingCylinder() = 0;

		// Method called on the end of every simulation.
		virtual void clear() = 0;

		// Returns the deep copy of every object.
		// It is needed for the collision detection engine.
		virtual Entity * clone() const = 0;

		// Returns an renderable object trough which it is rendered by the simulation.
		virtual IRenderable * getRenderable() = 0;

		// Custom non-zero identificator of the object for later use.
		virtual int getType() const;

		// It is called on the end of every frame of the simulation.
		// Usually contains the updating of the position of the given object,
		// but can also influence other objects.
		virtual void onUpdate(double time_step) = 0;

		// Reverse the object to the previous frame, this is necessary for the collision deteciton algorithm
		virtual void reverse() = 0;

		// Returns true if object is not movable, default is set to to true.
		virtual bool isStatic() const;

		// Getters:
		inline boost::mutex * getLock()
		{
			return &lock_;
		}
		inline bool isCollidable() const
		{
			return collidable_;
		}
		inline bool isFrozen() const
		{
			return frozen_;
		}
		inline bool isInvisible() const
		{
			return invisible_;
		}

	protected:

		// When set to false it is skipped while collision detection.
		bool collidable_;

		// When set to true the onUpdate method is not called on this object.
		bool frozen_;

		// When set to true the render is not called on this object.
		bool invisible_;

		Entity(const Entity & entity);
		explicit Entity();

	private:

		// Lock for synchronized use.
		boost::mutex lock_;

		void init();
	};
}

#endif
